home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / checkbox / registries / hal.py < prev    next >
Text File  |  2009-11-05  |  16KB  |  467 lines

  1. #
  2. # This file is part of Checkbox.
  3. #
  4. # Copyright 2008 Canonical Ltd.
  5. #
  6. # Checkbox is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Checkbox is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import re
  20. import string
  21. import posixpath
  22.  
  23. from checkbox.lib.cache import cache
  24. from checkbox.lib.dmi import DmiNotAvailable
  25. from checkbox.lib.pci import Pci
  26. from checkbox.lib.usb import Usb
  27.  
  28. from checkbox.properties import String
  29. from checkbox.registry import Registry
  30. from checkbox.registries.command import CommandRegistry
  31. from checkbox.registries.link import LinkRegistry
  32. from checkbox.registries.map import MapRegistry
  33.  
  34.  
  35. class UnknownName(object):
  36.     def __init__(self, function):
  37.         self._function = function
  38.  
  39.     def __get__(self, instance, cls=None):
  40.         self._instance = instance
  41.         return self
  42.  
  43.     def __call__(self, *args, **kwargs):
  44.         name = self._function(self._instance, *args, **kwargs)
  45.         if name and name.startswith("Unknown ("):
  46.             name = None
  47.  
  48.         return name
  49.  
  50.  
  51. class DeviceRegistry(Registry):
  52.     """Registry for HAL device information.
  53.  
  54.     Each item contained in this registry consists of the properties of
  55.     the corresponding HAL device.
  56.     """
  57.  
  58.     def __init__(self, properties):
  59.         self._properties = properties
  60.  
  61.     def __str__(self):
  62.         strings = ["%s: %s" % (k, v) for k, v in self.items()
  63.             if not isinstance(v, Registry)]
  64.  
  65.         return "\n".join(strings)
  66.  
  67.     def _get_bus(self):
  68.         return self._properties.get("linux.subsystem")
  69.  
  70.     def _get_category(self):
  71.         if "system.hardware.vendor" in self._properties:
  72.             return "SYSTEM"
  73.  
  74.         if "net.interface" in self._properties:
  75.             return "NETWORK"
  76.  
  77.         if "pci.device_class" in self._properties:
  78.             class_id = self._properties["pci.device_class"]
  79.             subclass_id = self._properties["pci.device_subclass"]
  80.  
  81.             if class_id == Pci.BASE_CLASS_NETWORK:
  82.                 return "NETWORK"
  83.  
  84.             if class_id == Pci.BASE_CLASS_DISPLAY:
  85.                 return "VIDEO"
  86.  
  87.             if class_id == Pci.BASE_CLASS_SERIAL \
  88.                and subclass_id == Pci.CLASS_SERIAL_USB:
  89.                 return "USB"
  90.  
  91.             if class_id == Pci.BASE_CLASS_STORAGE:
  92.                 if subclass_id == Pci.CLASS_STORAGE_SCSI:
  93.                     return "SCSI"
  94.  
  95.                 if subclass_id == Pci.CLASS_STORAGE_IDE:
  96.                     return "IDE"
  97.  
  98.                 if subclass_id == Pci.CLASS_STORAGE_FLOPPY:
  99.                     return "FLOPPY"
  100.  
  101.                 if subclass_id == Pci.CLASS_STORAGE_RAID:
  102.                     return "RAID"
  103.  
  104.             if class_id == Pci.BASE_CLASS_COMMUNICATION \
  105.                and subclass_id == Pci.CLASS_COMMUNICATION_MODEM:
  106.                 return "MODEM"
  107.  
  108.             if class_id == Pci.BASE_CLASS_INPUT \
  109.                and subclass_id == Pci.CLASS_INPUT_SCANNER:
  110.                 return "SCANNER"
  111.  
  112.             if class_id == Pci.BASE_CLASS_MULTIMEDIA:
  113.                 if subclass_id == Pci.CLASS_MULTIMEDIA_VIDEO:
  114.                     return "CAPTURE"
  115.  
  116.                 if subclass_id == Pci.CLASS_MULTIMEDIA_AUDIO \
  117.                    or subclass_id == Pci.CLASS_MULTIMEDIA_AUDIO_DEVICE: \
  118.                     return "AUDIO"
  119.  
  120.             if class_id == Pci.BASE_CLASS_SERIAL \
  121.                and subclass_id == Pci.CLASS_SERIAL_FIREWIRE:
  122.                 return "FIREWIRE"
  123.  
  124.             if class_id == Pci.BASE_CLASS_BRIDGE \
  125.                and (subclass_id == Pci.CLASS_BRIDGE_PCMCIA \
  126.                     or subclass_id == Pci.CLASS_BRIDGE_CARDBUS):
  127.                 return "SOCKET"
  128.  
  129.         if "usb.interface.class" in self._properties:
  130.             interface_class = self._properties["usb.interface.class"]
  131.             interface_subclass = self._properties["usb.interface.subclass"]
  132.  
  133.             if interface_class == Usb.BASE_CLASS_AUDIO:
  134.                 return "AUDIO"
  135.  
  136.             if interface_class == Usb.BASE_CLASS_PRINTER:
  137.                 return "PRINTER"
  138.  
  139.             if interface_class == Usb.BASE_CLASS_STORAGE:
  140.                 if interface_subclass == Usb.CLASS_STORAGE_FLOPPY:
  141.                     return "FLOPPY"
  142.  
  143.                 if interface_subclass == Usb.CLASS_STORAGE_SCSI:
  144.                     return "SCSI"
  145.  
  146.             if interface_class == Usb.BASE_CLASS_VIDEO:
  147.                 return "VIDEO"
  148.  
  149.             if interface_class == Usb.BASE_CLASS_WIRELESS:
  150.                 return "NETWORK"
  151.  
  152.         if "info.capabilities" in self._properties:
  153.             capabilities = self._properties["info.capabilities"]
  154.             if "input.keyboard" in capabilities:
  155.                 return "KEYBOARD"
  156.  
  157.             if "input.mouse" in capabilities:
  158.                 return "MOUSE"
  159.  
  160.         if "storage.drive_type" in self._properties:
  161.             drive_type = self._properties["storage.drive_type"]
  162.             if drive_type == "cdrom":
  163.                 return "CDROM"
  164.  
  165.             if drive_type == "disk":
  166.                 return "DISK"
  167.  
  168.             if drive_type == "floppy":
  169.                 return "FLOPPY"
  170.  
  171.         if "scsi.type" in self._properties:
  172.             type = self._properties["scsi.type"]
  173.             if type == "disk":
  174.                 return "DISK"
  175.  
  176.             if type == "tape":
  177.                 return "TAPE"
  178.  
  179.             if type == "printer":
  180.                 return "PRINTER"
  181.  
  182.             if type == "cdrom":
  183.                 return "CDROM"
  184.  
  185.             if type == "scanner":
  186.                 return "SCANNER"
  187.  
  188.             if type == "raid":
  189.                 return "RAID"
  190.  
  191.         if self._get_product_id():
  192.             return "OTHER"
  193.  
  194.         return None
  195.  
  196.     def _get_driver(self):
  197.         return self._properties.get("info.linux.driver")
  198.  
  199.     def _get_path(self):
  200.         return self._properties.get("linux.sysfs_path", "").replace("/sys", "")
  201.  
  202.     def _get_product_id(self):
  203.         if "info.subsystem" in self._properties:
  204.             product_id = "%s.product_id" % self._properties["info.subsystem"]
  205.             if product_id in self._properties:
  206.                 return self._properties[product_id]
  207.  
  208.         # pnp
  209.         if "pnp.id" in self._properties:
  210.             match = re.match(r"^(?P<vendor_name>.*)(?P<product_id>[%s]{4})$"
  211.                 % string.hexdigits, self._properties["pnp.id"])
  212.             if match:
  213.                 return int(match.group("product_id"), 16)
  214.  
  215.         return None
  216.  
  217.     def _get_vendor_id(self):
  218.         if "info.subsystem" in self._properties:
  219.             vendor_id = "%s.vendor_id" % self._properties["info.subsystem"]
  220.             if vendor_id in self._properties:
  221.                 return self._properties[vendor_id]
  222.  
  223.         return None
  224.  
  225.     def _get_subproduct_id(self):
  226.         return self._properties.get("pci.subsys_product_id")
  227.  
  228.     def _get_subvendor_id(self):
  229.         return self._properties.get("pci.subsys_vendor_id")
  230.  
  231.     @UnknownName
  232.     def _get_product(self):
  233.         bus = self._get_bus()
  234.  
  235.         # Ignore subsystems using parent or generated names
  236.         if bus in ("drm", "net", "platform", "pci", "pnp", "scsi_generic",
  237.                    "scsi_host", "tty", "usb", "video4linux"):
  238.             return None
  239.  
  240.         if "usb.interface.number" in self._properties:
  241.             return None
  242.  
  243.         if self._properties.get("info.category") == "ac_adapter":
  244.             return None
  245.  
  246.         for property in ("alsa.device_id",
  247.                          "alsa.card_id",
  248.                          "sound.card_id",
  249.                          "battery.model",
  250.                          "ieee1394.product",
  251.                          "killswitch.name",
  252.                          "oss.device_id",
  253.                          "scsi.model",
  254.                          "system.hardware.product",
  255.                          "info.product"):
  256.             if property in self._properties:
  257.                 return self._properties[property]
  258.  
  259.         return None
  260.  
  261.     @UnknownName
  262.     def _get_vendor(self):
  263.         bus = self._get_bus()
  264.  
  265.         # Ignore subsystems using parent or generated names
  266.         if bus in ("drm", "pci", "rfkill", "usb"):
  267.             return None
  268.  
  269.         # pnp
  270.         if "pnp.id" in self._properties:
  271.             match = re.match(r"^(?P<vendor_name>.*)(?P<product_id>[%s]{4})$"
  272.                 % string.hexdigits, self._properties["pnp.id"])
  273.             if match:
  274.                 return match.group("vendor_name")
  275.  
  276.         for property in ("battery.vendor",
  277.                          "ieee1394.vendor",
  278.                          "scsi.vendor",
  279.                          "system.hardware.vendor",
  280.                          "info.vendor"):
  281.             if property in self._properties:
  282.                 return self._properties[property]
  283.  
  284.         return None
  285.  
  286.     def items(self):
  287.         return (
  288.             ("path", self._get_path()),
  289.             ("bus", self._get_bus()),
  290.             ("category", self._get_category()),
  291.             ("driver", self._get_driver()),
  292.             ("product_id", self._get_product_id()),
  293.             ("vendor_id", self._get_vendor_id()),
  294.             ("subproduct_id", self._get_subproduct_id()),
  295.             ("subvendor_id", self._get_subvendor_id()),
  296.             ("product", self._get_product()),
  297.             ("vendor", self._get_vendor()),
  298.             ("properties", MapRegistry(self._properties)),
  299.             ("device", LinkRegistry(self)))
  300.  
  301.  
  302. class DmiDeviceRegistry(DeviceRegistry):
  303.  
  304.     _category_to_property = {
  305.         "BIOS": "system.firmware",
  306.         "BOARD": "system.board",
  307.         "CHASSIS": "system.chassis"}
  308.  
  309.     def __init__(self, properties, category):
  310.         super(DmiDeviceRegistry, self).__init__(properties)
  311.         if category not in self._category_to_property:
  312.             raise Exception, "Unsupported category: %s" % category
  313.  
  314.         self._category = category
  315.  
  316.     @property
  317.     def _property(self):
  318.         return self._category_to_property[self._category]
  319.  
  320.     def _get_category(self):
  321.         return self._category
  322.  
  323.     def _get_path(self):
  324.         path = super(DmiDeviceRegistry, self)._get_path()
  325.         return posixpath.join(path, self._category.lower())
  326.  
  327.     def _get_product(self):
  328.         for subproperty in "product", "type", "version":
  329.             property = "%s.%s" % (self._property, subproperty)
  330.             product = self._properties.get(property)
  331.             if product and product != "Not Available":
  332.                 return product
  333.  
  334.         return None
  335.  
  336.     @DmiNotAvailable
  337.     def _get_vendor(self):
  338.         for subproperty in "vendor", "manufacturer":
  339.             property = "%s.%s" % (self._property, subproperty)
  340.             if property in self._properties:
  341.                 return self._properties[property]
  342.  
  343.         return None
  344.  
  345.  
  346. class HalRegistry(CommandRegistry):
  347.     """Registry for HAL information.
  348.  
  349.     Each item contained in this registry consists of the udi as key and
  350.     the corresponding device registry as value.
  351.     """
  352.  
  353.     # Command to retrieve hal information.
  354.     command = String(default="lshal")
  355.  
  356.     # See also section "Deprecated Properties" of the "HAL 0.5.10 Specification",
  357.     # available from http://people.freedesktop.org/~david/hal-spec/hal-spec.html
  358.     _deprecated_expressions = (
  359.         (r"info\.bus",                             "info.subsystem"),
  360.         (r"([^\.]+)\.physical_device",             "\1.originating_device"),
  361.         (r"power_management\.can_suspend_to_ram",  "power_management.can_suspend"),
  362.         (r"power_management\.can_suspend_to_disk", "power_management.can_hibernate"),
  363.         (r"smbios\.system\.manufacturer",          "system.hardware.vendor"),
  364.         (r"smbios\.system\.product",               "system.hardware.product"),
  365.         (r"smbios\.system\.version",               "system.hardware.version"),
  366.         (r"smbios\.system\.serial",                "system.hardware.serial"),
  367.         (r"smbios\.system\.uuid",                  "system.hardware.uuid"),
  368.         (r"smbios\.bios\.vendor",                  "system.firmware.vendor"),
  369.         (r"smbios\.bios\.version",                 "system.firmware.version"),
  370.         (r"smbios\.bios\.release_date",            "system.firmware.release_date"),
  371.         (r"smbios\.chassis\.manufacturer",         "system.chassis.manufacturer"),
  372.         (r"smbios\.chassis\.type",                 "system.chassis.type"),
  373.         (r"system\.vendor",                        "system.hardware.vendor"),
  374.         (r"usb_device\.speed_bcd",                 "usb_device.speed"),
  375.         (r"usb_device\.version_bcd",               "usb_device.version"))
  376.  
  377.     def __init__(self, *args, **kwargs):
  378.         super(HalRegistry, self).__init__(*args, **kwargs)
  379.         self._deprecated_patterns = ((re.compile("^%s$" % a), b)
  380.             for (a, b) in self._deprecated_expressions)
  381.  
  382.     def _get_key(self, key):
  383.         for (old, new) in self._deprecated_patterns:
  384.             key = old.sub(new, key)
  385.  
  386.         return key
  387.  
  388.     def _get_value(self, value, type):
  389.         value = value.strip()
  390.         if type == "bool":
  391.             value = bool(value == "true")
  392.         elif type == "double":
  393.             value = float(value.split()[0])
  394.         elif type == "int" or type == "uint64":
  395.             value = int(value.split()[0])
  396.         elif type == "string":
  397.             value = str(value.strip("'"))
  398.         elif type == "string list":
  399.             value = [v.strip("'")
  400.                     for v in value.strip("{}").split(", ")]
  401.         else:
  402.             raise Exception, "Unknown type: %s" % type
  403.  
  404.         return value
  405.  
  406.     def _ignore_device(self, device):
  407.         # Ignore devices without bus information
  408.         if not device.bus:
  409.             return True
  410.  
  411.         # Ignore devices without product information
  412.         if not device.product and device.product_id is None:
  413.             return True
  414.  
  415.         # Ignore invalid subsystem information
  416.         if (device.subproduct_id is None and device.subvendor_id is not None) \
  417.            or (device.subproduct_id is not None and device.subvendor_id is None):
  418.             return True
  419.  
  420.         # Ignore virtual devices except for dmi information
  421.         if device.bus != "dmi" \
  422.            and "virtual" in device.path.split(posixpath.sep):
  423.             return True
  424.  
  425.         return False
  426.  
  427.     @cache
  428.     def items(self):
  429.         devices = []
  430.         for record in self.split("\n\n"):
  431.             if not record:
  432.                 continue
  433.  
  434.             name = None
  435.             properties = {}
  436.             for line in record.split("\n"):
  437.                 match = re.match(r"udi = '(.*)'", line)
  438.                 if match:
  439.                     udi = match.group(1)
  440.                     name = udi.split(posixpath.sep)[-1]
  441.                     continue
  442.  
  443.                 match = re.match(r"  (?P<key>.*) = (?P<value>.*) \((?P<type>.*?)\)", line)
  444.                 if match:
  445.                     key = self._get_key(match.group("key"))
  446.                     value = self._get_value(match.group("value"),
  447.                         match.group("type"))
  448.                     properties[key] = value
  449.  
  450.             if name == "computer":
  451.                 properties["linux.subsystem"] = "dmi"
  452.                 properties["linux.sysfs_path"] = "/sys/devices/virtual/dmi/id"
  453.  
  454.                 device = DeviceRegistry(properties)
  455.                 devices.append(device)
  456.                 for category in "BIOS", "BOARD", "CHASSIS":
  457.                     device = DmiDeviceRegistry(properties, category)
  458.                     devices.append(device)
  459.             else:
  460.                 device = DeviceRegistry(properties)
  461.                 devices.append(device)
  462.  
  463.         return [(d.path, d) for d in devices if not self._ignore_device(d)]
  464.  
  465.  
  466. factory = HalRegistry
  467.